home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1993 / Internet Info CD-ROM (Walnut Creek) (1993).iso / networking / terms / tip / value.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-10-09  |  5.8 KB  |  333 lines

  1. /*
  2.  * Copyright (c) 1983 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #ifndef lint
  19. static char sccsid[] = "@(#)value.c    5.2 (Berkeley) 9/2/88";
  20. #endif /* not lint */
  21.  
  22. #include "tip.h"
  23.  
  24. #define MIDDLE    35
  25.  
  26. static value_t *vlookup();
  27. static int col = 0;
  28.  
  29. /*
  30.  * Variable manipulation
  31.  */
  32. vinit()
  33. {
  34.     register value_t *p;
  35.     register char *cp;
  36.     FILE *f;
  37.     char file[256];
  38.  
  39.     for (p = vtable; p->v_name != NULL; p++) {
  40.         if (p->v_type&ENVIRON)
  41.             if (cp = getenv(p->v_name))
  42.                 p->v_value = cp;
  43.         if (p->v_type&IREMOTE)
  44.             number(p->v_value) = *address(p->v_value);
  45.     }
  46.     /*
  47.      * Read the .tiprc file in the HOME directory
  48.      *  for sets
  49.      */
  50.     strcpy(file, value(HOME));
  51.     strcat(file, "/.tiprc");
  52.     if ((f = fopen(file, "r")) != NULL) {
  53.         register char *tp;
  54.  
  55.         while (fgets(file, sizeof(file)-1, f) != NULL) {
  56.             if (vflag)
  57.                 printf("set %s", file);
  58.             if (tp = rindex(file, '\n'))
  59.                 *tp = '\0';
  60.             vlex(file);
  61.         }
  62.         fclose(f);
  63.     }
  64.     /*
  65.      * To allow definition of exception prior to fork
  66.      */
  67.     vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC);
  68. }
  69.  
  70. /*VARARGS1*/
  71. vassign(p, v)
  72.     register value_t *p;
  73.     char *v;
  74. {
  75.  
  76.     if (!vaccess(p->v_access, WRITE)) {
  77.         printf("access denied\r\n");
  78.         return;
  79.     }
  80.     switch (p->v_type&TMASK) {
  81.  
  82.     case STRING:
  83.         if (equal(p->v_value, v))
  84.             return;
  85.         if (!(p->v_type&(ENVIRON|INIT)))
  86.             free(p->v_value);
  87.         if ((p->v_value = malloc(size(v)+1)) == NOSTR) {
  88.             printf("out of core\r\n");
  89.             return;
  90.         }
  91.         p->v_type &= ~(ENVIRON|INIT);
  92.         strcpy(p->v_value, v);
  93.         break;
  94.  
  95.     case NUMBER:
  96.         if (number(p->v_value) == number(v))
  97.             return;
  98.         number(p->v_value) = number(v);
  99.         break;
  100.  
  101.     case BOOL:
  102.         if (boolean(p->v_value) == (*v != '!'))
  103.             return;
  104.         boolean(p->v_value) = (*v != '!');
  105.         break;
  106.  
  107.     case CHAR:
  108.         if (character(p->v_value) == *v)
  109.             return;
  110.         character(p->v_value) = *v;
  111.     }
  112.     p->v_access |= CHANGED;
  113. }
  114.  
  115. vlex(s)
  116.     register char *s;
  117. {
  118.     register value_t *p;
  119.  
  120.     if (equal(s, "all")) {
  121.         for (p = vtable; p->v_name; p++)
  122.             if (vaccess(p->v_access, READ))
  123.                 vprint(p);
  124.     } else {
  125.         register char *cp;
  126.  
  127.         do {
  128.             if (cp = vinterp(s, ' '))
  129.                 cp++;
  130.             vtoken(s);
  131.             s = cp;
  132.         } while (s);
  133.     }
  134.     if (col > 0) {
  135.         printf("\r\n");
  136.         col = 0;
  137.     }
  138. }
  139.  
  140. static int
  141. vtoken(s)
  142.     register char *s;
  143. {
  144.     register value_t *p;
  145.     register char *cp;
  146.     char *expand();
  147.  
  148.     if (cp = index(s, '=')) {
  149.         *cp = '\0';
  150.         if (p = vlookup(s)) {
  151.             cp++;
  152.             if (p->v_type&NUMBER)
  153.                 vassign(p, atoi(cp));
  154.             else {
  155.                 if (strcmp(s, "record") == 0)
  156.                     cp = expand(cp);
  157.                 vassign(p, cp);
  158.             }
  159.             return;
  160.         }
  161.     } else if (cp = index(s, '?')) {
  162.         *cp = '\0';
  163.         if ((p = vlookup(s)) && vaccess(p->v_access, READ)) {
  164.             vprint(p);
  165.             return;
  166.         }
  167.     } else {
  168.         if (*s != '!')
  169.             p = vlookup(s);
  170.         else
  171.             p = vlookup(s+1);
  172.         if (p != NOVAL) {
  173.             vassign(p, s);
  174.             return;
  175.         }
  176.     }
  177.     printf("%s: unknown variable\r\n", s);
  178. }
  179.  
  180. static int
  181. vprint(p)
  182.     register value_t *p;
  183. {
  184.     register char *cp;
  185.     extern char *interp(), *ctrl();
  186.  
  187.     if (col > 0 && col < MIDDLE)
  188.         while (col++ < MIDDLE)
  189.             putchar(' ');
  190.     col += size(p->v_name);
  191.     switch (p->v_type&TMASK) {
  192.  
  193.     case BOOL:
  194.         if (boolean(p->v_value) == FALSE) {
  195.             col++;
  196.             putchar('!');
  197.         }
  198.         printf("%s", p->v_name);
  199.         break;
  200.  
  201.     case STRING:
  202.         printf("%s=", p->v_name);
  203.         col++;
  204.         if (p->v_value) {
  205.             cp = interp(p->v_value, NULL);
  206.             col += size(cp);
  207.             printf("%s", cp);
  208.         }
  209.         break;
  210.  
  211.     case NUMBER:
  212.         col += 6;
  213.         printf("%s=%-5d", p->v_name, number(p->v_value));
  214.         break;
  215.  
  216.     case CHAR:
  217.         printf("%s=", p->v_name);
  218.         col++;
  219.         if (p->v_value) {
  220.             cp = ctrl(character(p->v_value));
  221.             col += size(cp);
  222.             printf("%s", cp);
  223.         }
  224.         break;
  225.     }
  226.     if (col >= MIDDLE) {
  227.         col = 0;
  228.         printf("\r\n");
  229.         return;
  230.     }
  231. }
  232.  
  233.  
  234. static int
  235. vaccess(mode, rw)
  236.     register unsigned mode, rw;
  237. {
  238.     if (mode & (rw<<PUBLIC))
  239.         return (1);
  240.     if (mode & (rw<<PRIVATE))
  241.         return (1);
  242.     return ((mode & (rw<<ROOT)) && getuid() == 0);
  243. }
  244.  
  245. static value_t *
  246. vlookup(s)
  247.     register char *s;
  248. {
  249.     register value_t *p;
  250.  
  251.     for (p = vtable; p->v_name; p++)
  252.         if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s)))
  253.             return (p);
  254.     return (NULL);
  255. }
  256.  
  257. char *
  258. vinterp(s, stop)
  259.     register char *s;
  260.     char stop;
  261. {
  262.     register char *p = s, c;
  263.     int num;
  264.  
  265.     while ((c = *s++) && c != stop)
  266.         switch (c) {
  267.  
  268.         case '^':
  269.             if (*s)
  270.                 *p++ = *s++ - 0100;
  271.             else
  272.                 *p++ = c;
  273.             break;
  274.  
  275.         case '\\':
  276.             num = 0;
  277.             c = *s++;
  278.             if (c >= '0' && c <= '7')
  279.                 num = (num<<3)+(c-'0');
  280.             else {
  281.                 register char *q = "n\nr\rt\tb\bf\f";
  282.  
  283.                 for (; *q; q++)
  284.                     if (c == *q++) {
  285.                         *p++ = *q;
  286.                         goto cont;
  287.                     }
  288.                 *p++ = c;
  289.             cont:
  290.                 break;
  291.             }
  292.             if ((c = *s++) >= '0' && c <= '7') {
  293.                 num = (num<<3)+(c-'0');
  294.                 if ((c = *s++) >= '0' && c <= '7')
  295.                     num = (num<<3)+(c-'0');
  296.                 else
  297.                     s--;
  298.             } else
  299.                 s--;
  300.             *p++ = num;
  301.             break;
  302.  
  303.         default:
  304.             *p++ = c;
  305.         }
  306.     *p = '\0';
  307.     return (c == stop ? s-1 : NULL);
  308. }
  309.  
  310. /*
  311.  * assign variable s with value v (for NUMBER or STRING or CHAR types)
  312.  */
  313.  
  314. vstring(s,v)
  315.     register char *s;
  316.     register char *v;
  317. {
  318.     register value_t *p;
  319.     char *expand();
  320.  
  321.     p = vlookup(s); 
  322.     if (p == 0)
  323.         return (1);
  324.     if (p->v_type&NUMBER)
  325.         vassign(p, atoi(v));
  326.     else {
  327.         if (strcmp(s, "record") == 0)
  328.             v = expand(v);
  329.         vassign(p, v);
  330.     }
  331.     return (0);
  332. }
  333.